#!/usr/bin/env node

/**
 * MCP 测试监控服务器
 * 让 Cursor AI 能够直接运行测试并获取结果
 */

const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
const { CallToolRequestSchema, ListToolsRequestSchema } = require('@modelcontextprotocol/sdk/types.js');
const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');

// 创建 MCP 服务器
const server = new Server(
  {
    name: 'fun-english-test-monitor',
    version: '1.0.0',
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// 项目根目录
const PROJECT_ROOT = path.join(__dirname, '..');

// 工具列表
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: 'run_all_tests',
        description: '运行所有Playwright测试并返回结果',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'run_admin_tests',
        description: '只运行管理员后台测试',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'run_student_tests',
        description: '只运行学生端测试',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'get_test_report',
        description: '获取最新的测试报告',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'run_specific_test',
        description: '运行指定的测试',
        inputSchema: {
          type: 'object',
          properties: {
            testName: {
              type: 'string',
              description: '测试名称，例如: "管理员登录"',
            },
          },
          required: ['testName'],
        },
      },
      {
        name: 'check_services',
        description: '检查前端和后端服务是否运行',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
    ],
  };
});

// 执行测试的辅助函数
function runTest(command) {
  return new Promise((resolve) => {
    exec(command, { cwd: PROJECT_ROOT }, (error, stdout, stderr) => {
      const output = stdout + stderr;
      
      // 尝试读取JSON报告
      let report = null;
      try {
        const reportPath = path.join(PROJECT_ROOT, 'test-results', 'results.json');
        if (fs.existsSync(reportPath)) {
          report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
        }
      } catch (e) {
        // 忽略
      }
      
      resolve({
        success: error === null,
        output,
        report,
        exitCode: error ? error.code : 0,
      });
    });
  });
}

// 检查服务状态
async function checkServices() {
  const http = require('http');
  
  const checkService = (url) => {
    return new Promise((resolve) => {
      http.get(url, (res) => {
        resolve({ running: res.statusCode === 200, status: res.statusCode });
      }).on('error', () => {
        resolve({ running: false, status: 'ERROR' });
      });
    });
  };
  
  const [frontend, backend] = await Promise.all([
    checkService('http://localhost:5173'),
    checkService('http://localhost:3001/api/health'),
  ]);
  
  return {
    frontend,
    backend,
    ready: frontend.running && backend.running,
  };
}

// 工具调用处理
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  
  try {
    switch (name) {
      case 'run_all_tests': {
        const result = await runTest('npx playwright test --reporter=json');
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({
                message: '所有测试执行完成',
                result,
                summary: result.report ? {
                  total: result.report.stats?.expected || 0,
                  passed: result.report.stats?.expected || 0,
                  failed: result.report.stats?.unexpected || 0,
                } : null,
              }, null, 2),
            },
          ],
        };
      }
      
      case 'run_admin_tests': {
        const result = await runTest('npx playwright test tests/admin.spec.js --reporter=json');
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({
                message: '管理员测试执行完成',
                result,
              }, null, 2),
            },
          ],
        };
      }
      
      case 'run_student_tests': {
        const result = await runTest('npx playwright test tests/student.spec.js --reporter=json');
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({
                message: '学生端测试执行完成',
                result,
              }, null, 2),
            },
          ],
        };
      }
      
      case 'run_specific_test': {
        const testName = args.testName;
        const result = await runTest(`npx playwright test -g "${testName}" --reporter=json`);
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({
                message: `测试 "${testName}" 执行完成`,
                result,
              }, null, 2),
            },
          ],
        };
      }
      
      case 'get_test_report': {
        const reportPath = path.join(PROJECT_ROOT, 'test-results', 'results.json');
        if (fs.existsSync(reportPath)) {
          const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
          return {
            content: [
              {
                type: 'text',
                text: JSON.stringify({
                  message: '测试报告',
                  report,
                }, null, 2),
              },
            ],
          };
        } else {
          return {
            content: [
              {
                type: 'text',
                text: JSON.stringify({
                  message: '没有找到测试报告，请先运行测试',
                }, null, 2),
              },
            ],
          };
        }
      }
      
      case 'check_services': {
        const services = await checkServices();
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({
                message: '服务状态检查',
                services,
                recommendation: services.ready 
                  ? '✅ 前端和后端都在运行，可以开始测试'
                  : '⚠️ 请先启动前端和后端服务',
              }, null, 2),
            },
          ],
        };
      }
      
      default:
        throw new Error(`Unknown tool: ${name}`);
    }
  } catch (error) {
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify({
            error: error.message,
            stack: error.stack,
          }, null, 2),
        },
      ],
      isError: true,
    };
  }
});

// 启动服务器
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error('Fun English Test Monitor MCP server running on stdio');
}

main().catch((error) => {
  console.error('Server error:', error);
  process.exit(1);
});

